﻿#ifndef XCUSTOMCHARTLIST_H
#define XCUSTOMCHARTLIST_H

#include "qcustomplot.h"

template <class T>
class XCustomChartList
{
public:
    explicit XCustomChartList(QCustomPlot *parent = nullptr) : chartListParent(parent) { }
    ~XCustomChartList() { chartListParent = nullptr; }

    // getters
    int chartCount() const { return chartList.count(); }
    bool isEmpty() const { return chartList.isEmpty(); }
    T &at(int index) const { return chartList.at(index); }

    // add
    /*!
     * \brief addHeadChart
     */
    void addHeadChart()
    {
        // create a new chart
        T *chart = new T(chartListParent);

        // push into list
        chartList.push_front(chart);

        chartListParent->replot();
    }

    /*!
     * \brief addHeadChart
     * \param chart
     */
    void addHeadChart(T *chart)
    {
        // judge
        if(!chart) { qDebug() << Q_FUNC_INFO << "invalid chart!"; return; }

        // push into list
        chartList.push_front(chart);

        chartListParent->replot();
    }

    /*!
     * \brief addBackChart
     */
    void addBackChart()
    {
        // create a new chart
        T *chart = new T(chartListParent);

        // push into list
        chartList.push_back(chart);

        chartListParent->replot();
    }

    /*!
     * \brief addBackChart
     * \param chart
     */
    void addBackChart(T *chart)
    {
        // judge
        if(!chart) { qDebug() << Q_FUNC_INFO << "invalid chart!"; return; }

        // push into list
        chartList.push_back(chart);

        chartListParent->replot();
    }

    /*!
     * \brief addChart
     * \param index
     */
    void addChart(int index = -1)
    {
        if(-1 == index) { addBackChart(); return; }

        if(index < 0 && index > chartCount()) { qDebug() << Q_FUNC_INFO << "invalid index!"; return; }

        // create a new pointLine
        T *chart = new T(chartListParent);

        // insert into list
        chartList.insert(index, chart);

        chartListParent->replot();
    }

    /*!
     * \brief addChart
     * \param chart
     * \param index
     */
    void addChart(T *chart, int index = -1)
    {
        if(-1 == index) { addBackChart(chart); return; }

        if(index < 0 && index > chartCount()) { qDebug() << Q_FUNC_INFO << "invalid index!"; return; }

        // insert into list
        chartList.insert(index, chart);

        chartListParent->replot();
    }

    // delete
    /*!
     * \brief deleteFirstChart
     */
    void deleteFirstChart()
    {
        if(chartList.isEmpty()) { qDebug() << Q_FUNC_INFO << "empty!"; return; }

        // delete
        delete chartList.first();
        chartList.first() = nullptr;
        chartList.pop_front();

        chartListParent->replot();
    }

    /*!
     * \brief deleteLastChart
     */
    void deleteLastChart()
    {
        if(chartList.isEmpty()) return;

        // delete
        delete chartList.last();
        chartList.last() = nullptr;
        chartList.pop_back();

        chartListParent->replot();
    }

    /*!
     * \brief deleteChart
     * \param index
     */
    void deleteChart(int index = -1)
    {
        if(-1 == index) { deleteBackChart(); return; }

        if(index < 0 && index > chartCount()) { qDebug() << Q_FUNC_INFO << "invalid index!"; return; }

        // delete
        delete chartList.at(index);
        chartList.at(index) = nullptr;
        chartList.removeAt(index);

        chartListParent->replot();
    }

    // clear
    /*!
     * \brief clearCharts
     */
    void clearCharts()
    {
        if(chartList.isEmpty()) { qDebug() << Q_FUNC_INFO << "empty!"; return; }

        qDeleteAll(chartList);
        chartList.clear();

        chartListParent->replot();
    }

    // adjust
    /*!
     * \brief exChangeOrder
     * \param currentIndex
     * \param objectiveIndex
     */
    void exChangeOrder(int currentIndex, int objectiveIndex)
    {
        if(currentIndex == objectiveIndex) { qDebug() << Q_FUNC_INFO << "same index!"; return; }
        if(chartList.count() < 2)  { qDebug() << Q_FUNC_INFO << "cannot exchange!"; return; }

        chartList.move(qBound(0, currentIndex, chartList.size() - 1),  qBound(0, objectiveIndex, chartList.size() - 1));

        chartListParent->replot();
    }

    /*!
     * \brief exChangeOrder
     * \param chart
     * \param objectiveIndex
     */
    void exChangeOrder(T *chart, int objectiveIndex)
    {
        changeOrder(chartList.indexOf(chart), objectiveIndex);
    }

private:
    QList<T*> chartList;
    QCustomPlot *chartListParent = nullptr;

signals:
    void chartListChanged();
};

#endif // XCUSTOMCHARTLIST_H
